他のプログラミング言語を経験してからRをいじりだした人に多いと思うのですが、便利関数で簡潔に実現できる処理を、ループ処理で複雑に書いて、苦労した上に見通しとパフォーマンスが悪いコードを生成することがあります。
1 ベクトルの中から指定した要素の位置を特定する
which
関数で簡単にできます。
試しに1から10までの並びがランダムなベクトルを作って使ってみましょう。
<- (1:10)[order(runif(10))]) (v
[1] 1 4 3 9 6 7 2 10 8 5
6
の位置を探します。
<- which(v == 6)) (i
[1] 5
v[i]
[1] 6
行列の場合はarr.ind=TRUE
オプションをつけておくと、行番号と列番号をそれぞれ得られます。
<- matrix((1:12)[order(runif(12))], 4, 3)) (w
[,1] [,2] [,3]
[1,] 5 12 11
[2,] 10 6 8
[3,] 7 3 2
[4,] 1 9 4
<- which(w == 6, arr.ind = TRUE)) (i
row col
[1,] 2 2
w[i]
[1] 6
2 ベクトルの要素で重複分を特定
<- c(1:10, 5, 9, 5)
x duplicated(x)
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE
[13] TRUE
duplicated(x)] x[
[1] 5 9 5
最初に出現する5
と9
は重複分としてカウントされません。なお、unique
を使うと重複なしベクトルにできます。
3 分岐
Rにもswitch
文がありました。
switch("a", a = 123, b = 456, c = 789)
[1] 123
switch("b", a = 123, b = 456, c = 789)
[1] 456
switch("c", a = 123, b = 456, c = 789)
[1] 789
4 ベクトルを分割
男女など属性ごとにベクトルを分けたいときに便利です。
<- 1:9) (x
[1] 1 2 3 4 5 6 7 8 9
<- as.factor(rep(letters[1:3], 3))) (g
[1] a b c a b c a b c
Levels: a b c
split(x, g)
$a
[1] 1 4 7
$b
[1] 2 5 8
$c
[1] 3 6 9
文字列を分割する場合はstrsplit
を使います。
5 ランクを計算
ベクトル内での昇順の順位を示します。同順の場合の処理はties.method
で指定です。
<- round(runif(10, min = 1, max = 10))) (x
[1] 4 8 8 3 7 5 4 9 9 5
rank(x)
[1] 2.5 7.5 7.5 1.0 6.0 4.5 2.5 9.5 9.5 4.5
rank(x, ties.method = "min")
[1] 2 7 7 1 6 4 2 9 9 4
ゴルフの順位のようにn位タイを計算するのはちょっと手間かもです。
<- unique(x[duplicated(x)])
ties sprintf("%d位%s", rank(x, ties.method = "min"), ifelse(x %in% ties, "タイ", ""))
[1] "2位タイ" "7位タイ" "7位タイ" "1位" "6位" "4位タイ" "2位タイ"
[8] "9位タイ" "9位タイ" "4位タイ"
6 ベクトルの積集合と差集合
あんまり使った記憶が無いのですが、覚えていたら便利かもです。
<- letters[1:5]) (x
[1] "a" "b" "c" "d" "e"
<- letters[3:8]) (y
[1] "c" "d" "e" "f" "g" "h"
intersect(x, y)
[1] "c" "d" "e"
setdiff(x, y)
[1] "a" "b"
setdiff(y, x)
[1] "f" "g" "h"
7 segments
8 structure
9 上三角,下三角
<- matrix(1:25, 5, 5)
X upper.tri(X)
[,1] [,2] [,3] [,4] [,5]
[1,] FALSE TRUE TRUE TRUE TRUE
[2,] FALSE FALSE TRUE TRUE TRUE
[3,] FALSE FALSE FALSE TRUE TRUE
[4,] FALSE FALSE FALSE FALSE TRUE
[5,] FALSE FALSE FALSE FALSE FALSE
lower.tri(X, diag = TRUE)
[,1] [,2] [,3] [,4] [,5]
[1,] TRUE FALSE FALSE FALSE FALSE
[2,] TRUE TRUE FALSE FALSE FALSE
[3,] TRUE TRUE TRUE FALSE FALSE
[4,] TRUE TRUE TRUE TRUE FALSE
[5,] TRUE TRUE TRUE TRUE TRUE
lower.tri(X)] <- NA
X[ X
[,1] [,2] [,3] [,4] [,5]
[1,] 1 6 11 16 21
[2,] NA 7 12 17 22
[3,] NA NA 13 18 23
[4,] NA NA NA 19 24
[5,] NA NA NA NA 25